<?php

class ContentList implements Iterator, Countable
{
	/**
	 * Elements of contentList.
	 * Each element instanceof ContentListElement.
	 * 
	 * @var array
	 */
	protected $_elements = array();
	
	/**
	 * ContentList name.
	 * 
	 * @var string
	 */
	protected $_name;
	
	/**
	 * Set name of ContentList.
	 * 
	 * @return void
	 */
	public function setName($name) 
	{
		$this->_name = $name;
	}
	
	/**
	 * Get name of ContentList.
	 * 
	 * @return string
	 */
	public function getName() 
	{
		return $this->_name;
	}
	
	/**
	 * Create new ContentList from Rowset object
	 *
	 * @param Zend_Db_Table_Rowset_Abstract
	 * @param string $type
	 * @return ContentList
	 * @throws Exception
	 */
	public static function fromRowset($rowset, $type = null)
	{
		//if (!$rowset instanceof Zend_Db_Table_Rowset_Abstract) {
		//	throw new Exception('For creating ContentList we need valid Rowset object');
		//} Закомменчено, т.к. нужна возможность передавать массив
				
		$contentlist = new self();
		foreach ($rowset as $row) {
			$contentlist->addElementByInterface($row, $type);
		}

		return $contentlist;
	}
	
	public static function fromRowset2($rowset, $params = array()) {
		
		$contentlist = ContentListElement::fromRowset($rowset, $params);
		
		return $contentlist;
	}

	/**
	 * Adding element to ContentList
	 *
	 * @param ContentListElement $element
	 * @return void
	 */
	public function addElement($element)
	{
		if (!$element instanceof ContentListElement) {
			throw new Exception('Element is not valid ContentListElement');
		}

		$this->_elements[] = $element;
	}

	/**
	 * Adding element by class implements IContentListElement
	 *
	 * @param IContentListElement $interface
	 * @param string $type
	 * @return void
	 */
	public function addElementByInterface($interface, $type = null)
	{
		if (!$interface instanceof IContentListElementProvider) {
			throw new Exception('Interface IContentListElementProvider not implemented');
		}
		
		$element = ContentListElement::fromRow($interface, $type);
		if($element)
			$this->addElement($element);
	}

    /**
     * Iteration index
     *
     * @var integer
     */
    protected $_index;

    /**
     * Defined by Countable interface
     *
     * @return int
     */
    public function count()
    {
        return count($this->_elements);
    }

    /**
     * Defined by Iterator interface
     *
     * @return mixed
     */
    public function current()
    {
        return current($this->_elements);
    }

    /**
     * Defined by Iterator interface
     *
     * @return mixed
     */
    public function key()
    {
        return key($this->_elements);
    }

    /**
     * Defined by Iterator interface
     *
     */
    public function next()
    {
        next($this->_elements);
        $this->_index++;
    }

    /**
     * Defined by Iterator interface
     *
     */
    public function rewind()
    {
        reset($this->_elements);
        $this->_index = 0;
    }

    /**
     * Defined by Iterator interface
     *
     * @return boolean
     */
    public function valid()
    {
        return $this->_index < $this->count();
    }
    
    /**
     * array_rand() for ContentList
     * Pick one or more random entries out of an ContentList elements.
     * 
     * @param integer $numRequired Specifies how many entries you want to pick
     * @return ContentList
     */
    public function rand($numRequired)
    {
    	if (!count($this->_elements)) {
    		return null;
    		throw new Exception('ContentList doesnt contain any elements');
    	}
    	
        if ($numRequired < 1) {
    		$numRequired = 1;
    	}
    	
    	if (count($this->_elements) < $numRequired) {
    		$numRequired = count($this->_elements);
    	}
    	
    	$keys = array_rand($this->_elements, $numRequired);
    	if(!$keys) return false;
    	foreach ($this->_elements as $key => $element) {
    		if (!in_array($key, $keys)) {
    			unset($this->_elements[$key]);
    		}
    	}
    }
}